package org.sonar.samples.java.checks;

import org.sonar.check.Rule;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*;
import org.sonar.plugins.java.api.semantic.Symbol;
import org.sonar.plugins.java.api.semantic.Type;

import java.util.*;

@Rule(key = "MyJavaRules34")
public class MyJavaRules34 extends IssuableSubscriptionVisitor {

    private final static String CHECK_TYPE_RespErrorBody = "RespErrorBody";

    private final static String CHECK_TYPE_RESPONSE = "Response";

    private final static String PROMPT = "接口返回值使用前应做非空检查。";

    // 用来存储已经检测过的 Response.java 对象符号
    private Set<Symbol> checkedSymbols;

    // 存储通过 new 创建的变量的符号
    private Set<Symbol> initializedWithNew = new HashSet<>();


    @Override
    public List<Tree.Kind> nodesToVisit() {
        // 只关心方法体中的变量声明、赋值和方法调用
        return Arrays.asList(Tree.Kind.METHOD);
    }

    @Override
    public void visitNode(Tree tree) {
        MethodTree methodTree = (MethodTree) tree;
        BlockTree blockTree = methodTree.block(); // 获取方法的代码块

        // 检查 blockTree 是否为 null
        if (blockTree == null || blockTree.body() == null) {
            return; // 如果方法体或方法体中的语句为空，则不进行任何检查
        }

        // 初始化已检测符号的集合
        checkedSymbols = new HashSet<>();
        // 遍历方法体中的每个语句
        blockTree.body().forEach(statement -> {
            if (statement.is(Tree.Kind.VARIABLE)) {
                // 跳过变量声明，后续调用需要检查非空
                VariableTree variableTree = (VariableTree) statement;
                Symbol variableSymbol = variableTree.symbol();
                // 获取变量的初始化表达式
                ExpressionTree initializer = variableTree.initializer();

                // 如果初始化表达式为 new 语句，跳过检查
                if (initializer != null && initializer.is(Tree.Kind.NEW_CLASS)) {
                    initializedWithNew.add(variableTree.symbol()); // 添加符号
                    return;  // 跳过该变量的 null 检查
                }

//                if (isResponseOrSubtype(variableSymbol.type())) {
//                    // 仅跳过声明，不对其进行检查
//                }
            } else if (statement.is(Tree.Kind.EXPRESSION_STATEMENT)) {
                // 对表达式语句（例如赋值和方法调用）进行检查
                ExpressionStatementTree expressionStatement = (ExpressionStatementTree) statement;
                checkExpression(expressionStatement.expression(), blockTree);
            }
        });
    }

    private void checkExpression(ExpressionTree expressionTree, BlockTree blockTree) {
        if (expressionTree.is(Tree.Kind.ASSIGNMENT)) {
            // 跳过赋值语句本身，后续调用需要检查非空
            AssignmentExpressionTree assignmentTree = (AssignmentExpressionTree) expressionTree;
            ExpressionTree variable = assignmentTree.variable();
            ExpressionTree assignedExpression = assignmentTree.expression();
            if (variable instanceof IdentifierTree) {
                Symbol variableSymbol = ((IdentifierTree) variable).symbol();

                // 如果赋值是通过 new 语句完成的，则跳过该检查
                if (assignedExpression.is(Tree.Kind.NEW_CLASS)) {
                    return; // 不报告问题，因为对象是通过 new 语句创建的
                }


//                if (isResponseOrSubtype(variableSymbol.type())) {
//                    // 赋值语句本身跳过检查
//                }
            }
        } else if (expressionTree.is(Tree.Kind.METHOD_INVOCATION)) {
            // 检查方法调用中的对象是否为自定义 Response 类型
            MethodInvocationTree methodInvocationTree = (MethodInvocationTree) expressionTree;
            ExpressionTree methodSelect = methodInvocationTree.methodSelect();
            if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
                MemberSelectExpressionTree memberSelect = (MemberSelectExpressionTree) methodSelect;
                ExpressionTree objectExpression = memberSelect.expression();

                if (objectExpression instanceof IdentifierTree) {
                    Symbol objectSymbol = ((IdentifierTree) objectExpression).symbol();
                    Type objectType = objectSymbol.type();

                    Type currentClass = null;
                    Type superClass = objectType.symbol().superClass();  // 父类
// 获取顶级父类
                    while (superClass != null && !superClass.is("java.lang.Object")) {
                        System.out.println("当前父类: " + superClass.fullyQualifiedName());
                        currentClass = superClass;
                        superClass = currentClass.symbol().superClass();  // 继续获取上一级父类
                    }

                    if (currentClass != null) {
                        System.out.println("顶级父类: " + currentClass.name());
                        System.out.println();
                    } else {
                        currentClass = objectType;
                    }


                    // 确保在使用前进行非空检查
                    if (isResponseOrSubtype(currentClass, objectType) && !checkedSymbols.contains(objectSymbol) && !initializedWithNew.contains(objectSymbol)) {



                        if (!isCheckedForNull(objectSymbol, blockTree)) {
                            reportIssue(methodInvocationTree, PROMPT);
                        }
                        checkedSymbols.add(objectSymbol);
                    }
                }
            }
        }
    }

    private boolean isResponseOrSubtype(Type type, Type ori) {
        // 判断是否是RespErrorBody或其子类 或Response类
//        return type.is(CHECK_TYPE_RespErrorBody) || type.isSubtypeOf(CHECK_TYPE_RespErrorBody) || type.is(CHECK_TYPE_RESPONSE);
        String name = type.name();
        String name1 = type.name();
        boolean a1 = CHECK_TYPE_RespErrorBody.equalsIgnoreCase(name);
        boolean a2 = CHECK_TYPE_RESPONSE.equalsIgnoreCase(name);
        boolean a3 = name.contains("Resp") || name.contains("resp");
        boolean a4 = name.contains("Response") || name.contains("response");
        boolean a5 = name1.contains("Resp") || name1.contains("resp");
        boolean a6 = name1.contains("Response") || name1.contains("response");
        return a1 || a2 || a3 || a4 || a5 || a6;
    }

    private boolean isCheckedForNull(Symbol symbol, BlockTree blockTree) {
        // 遍历代码块中的语句，查找非空检查
        for (StatementTree statement : blockTree.body()) {
            if (statement.is(Tree.Kind.IF_STATEMENT)) {
                IfStatementTree ifStatementTree = (IfStatementTree) statement;
                ExpressionTree condition = ifStatementTree.condition();

                if (condition.is(Tree.Kind.NOT_EQUAL_TO)) {
                    BinaryExpressionTree binaryExpressionTree = (BinaryExpressionTree) condition;

                    // 确保左操作数可以获取符号
                    ExpressionTree leftOperand = binaryExpressionTree.leftOperand();
                    if (leftOperand instanceof IdentifierTree) {
                        Symbol leftSymbol = ((IdentifierTree) leftOperand).symbol();

                        // 检查左操作数的符号是否与我们要检查的符号相同
                        if (leftSymbol.equals(symbol) &&
                                binaryExpressionTree.rightOperand().is(Tree.Kind.NULL_LITERAL)) {
                            return true; // 找到非空检查
                        }
                    }
                }
            }
        }
        return false; // 未找到非空检查
    }

    // 判断变量是否是通过 new 语句赋值
//    private boolean isAssignedWithNew(Symbol symbol, BlockTree blockTree) {
//        for (StatementTree statement : blockTree.body()) {
//            System.out.println(statement.kind());
//            if (statement.is(Tree.Kind.EXPRESSION_STATEMENT)) {
//                ExpressionStatementTree expressionStatement = (ExpressionStatementTree) statement;
//                ExpressionTree expression = expressionStatement.expression();
//
//                if (expression.is(Tree.Kind.ASSIGNMENT)) {
//                    AssignmentExpressionTree assignment = (AssignmentExpressionTree) expression;
//                    ExpressionTree variable = assignment.variable();
//                    ExpressionTree assignedExpression = assignment.expression();
//
//                    if (variable instanceof IdentifierTree && ((IdentifierTree) variable).symbol().equals(symbol)) {
//                        // 检查赋值表达式是否是 new 语句
//                        return assignedExpression.is(Tree.Kind.NEW_CLASS);
//                    }
//                }
//            }
//        }
//        return false;
//    }
}